//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <fcntl.h>

#include <time.h>
#include <errno.h>

#include <sys/stat.h>
#include <sys/times.h>
#include <sys/wait.h>

#include <iostream>
#include <fstream>

#include "libraries.h"
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#define  LENGTHTEXT                 10000
#define  PROGRAM_COMPACTPATTERNS    "bin/CompactPatternsFiles"
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
typedef char t_string [LENGTHTEXT];
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void panic (const char*);
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int main (int argc, char** argv) {
  
  String* filenameDirectories       = NULL;
  String* pathToProteinLINGOProject = NULL;
  String* pathToCATHFastaProfile    = NULL;
  
  if (argc < 4) {
    
    cout << "Error in the input parameters! Must by like: " << endl;
    cout << "./PipeProcessCompactPattern <In File - List of Directories to process>";
    cout <<                            " <Path to Protein LINGO Project executable>";
    cout <<                            " <Path to CATH Fasta Profile File>";
    cout << endl;
    
    return 0;
    
  }
  else {
    
    filenameDirectories       = new String(argv[1]);
    pathToProteinLINGOProject = new String(argv[2]);
    pathToCATHFastaProfile    = new String(argv[3]);
    
    cout << "------------------------------------------------------------------------------------------------------" << endl;
    cout << " In File - List of Directories to process : " << argv[1] << endl;
    cout << " Path to Protein LINGO Project executable : " << argv[2] << endl;
    cout << "          Path to CATH Fasta Profile File : " << argv[3] << endl;
    cout << "------------------------------------------------------------------------------------------------------" << endl;
    
  }
  
  pathToProteinLINGOProject->Trim();
  
  //Directory with the name of folder to process (the folder with the information of residues near to the ligands ordered by distance in angstrom)
  ifstream directoriesFile (filenameDirectories->Out());
  if (!directoriesFile.is_open()) return EXIT_FAILURE;
  cout << "Opening the file with the directories to process - " << filenameDirectories->Out() << endl;
  
  char    buffer [LENGTHTEXT + 1];
  String* bufferString = new String ();
  
  //Loop across the folders
  while (!directoriesFile.eof()) {
    
    directoriesFile.getline(buffer, LENGTHTEXT);
    
    bufferString->In(buffer);
    bufferString->Trim();
    
    if (pathToProteinLINGOProject->Out()[pathToProteinLINGOProject->Length() - 1] != '/') pathToProteinLINGOProject->Add("/");
        
    for (int j = 0; j < 5; j++) {

      String category;

      switch (j) {
        case 0  : category.In("AA"); break;
        case 1  : category.In("CH"); break;
        case 2  : category.In("PH"); break;
        case 3  : category.In("SS"); break;
        case 4  : category.In("MT"); break;
        default : category.In("AA"); break;
      }

      buffer[0] = '\0';

      sprintf(buffer, "%s%s \0",  pathToProteinLINGOProject->Out(), PROGRAM_COMPACTPATTERNS);
      sprintf(buffer, "%s %spatterns.%s.Pratt2.1.All.dat \0", buffer, bufferString->Out(), category.Out());

      char    tmpBufferFilename [LENGTHTEXT];
      fstream fileCheck;
      bool    existFile = false;

      tmpBufferFilename[0] = '\0';
      sprintf(tmpBufferFilename, "%spatterns.%s.Pratt2.1.20P.dat\0", bufferString->Out(), category.Out());
      fileCheck.open(tmpBufferFilename);
      if (fileCheck.is_open()) {
        existFile = true;
        sprintf(buffer, "%s %s \0", buffer, tmpBufferFilename);
        fileCheck.close();
      }

      tmpBufferFilename[0] = '\0';
      sprintf(tmpBufferFilename, "%spatterns.%s.Pratt2.1.40P.dat\0", bufferString->Out(), category.Out());
      fileCheck.open(tmpBufferFilename);
      if (fileCheck.is_open()) {
        existFile = true;
        sprintf(buffer, "%s %s \0", buffer, tmpBufferFilename);
        fileCheck.close();
      }

      tmpBufferFilename[0] = '\0';
      sprintf(tmpBufferFilename, "%spatterns.%s.Pratt2.1.60P.dat\0", bufferString->Out(), category.Out());
      fileCheck.open(tmpBufferFilename);
      if (fileCheck.is_open()) {
        existFile = true;
        sprintf(buffer, "%s %s \0", buffer, tmpBufferFilename);
        fileCheck.close();
      }

      tmpBufferFilename[0] = '\0';
      sprintf(tmpBufferFilename, "%spatterns.%s.Pratt2.1.80P.dat\0", bufferString->Out(), category.Out());
      fileCheck.open(tmpBufferFilename);
      if (fileCheck.is_open()) {
        existFile = true;
        sprintf(buffer, "%s %s \0", buffer, tmpBufferFilename);
        fileCheck.close();
      }

      tmpBufferFilename[0] = '\0';
      sprintf(tmpBufferFilename, "%spatterns.%s.Pratt2.1.90P.dat\0", bufferString->Out(), category.Out());
      fileCheck.open(tmpBufferFilename);
      if (fileCheck.is_open()) {
        existFile = true;
        sprintf(buffer, "%s %s \0", buffer, tmpBufferFilename);
        fileCheck.close();
      }

      if (existFile)
        system(buffer);

    }
        
  }
  
  directoriesFile.close();
  
  if (bufferString)              delete bufferString;
  
  if (filenameDirectories)       delete filenameDirectories;
  if (pathToProteinLINGOProject) delete pathToProteinLINGOProject;
  if (pathToCATHFastaProfile)    delete pathToCATHFastaProfile;

  return EXIT_SUCCESS;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void panic (const char *str) {
  
  t_string s;

  cout << str << endl;
  
  write(2, str, strlen(str));
  write(2, "\n", 1);
  
  if (errno != 0) {
    
    sprintf(s, "%d %s\n", errno, strerror(errno));
    write(2, s, strlen(s));
    
  }
  
  exit(0);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
